<template>
  <div class="bt822a">
      <el-card style="width: 100%; margin-bottom: 8px" shadow="hover">
        <template #default>
          <div class="form-default">
            <el-form :inline="true" :model="formInline" class="demo-form-inline">
              <el-form-item label="用户名称">
                <el-input v-model="formInline.user" placeholder="请输入" clearable />
              </el-form-item>
              <el-form-item label="用户部门">
                <el-select v-model="formInline.department" placeholder="请选择" clearable>
                  <el-option label="销售部门" value="abc" />
                  <el-option label="客服部门" value="xyz" />
                  <el-option label="财务部门" value="rst" />
                </el-select>
              </el-form-item>
              <el-form-item label="用户状态">
                <el-select v-model="formInline.status" placeholder="请选择" clearable>
                  <el-option label="启用" value="1" />
                  <el-option label="禁用" value="0" />
                </el-select>
              </el-form-item>
              <el-form-item label="创建日期">
                <el-date-picker v-model="formInline.creationDate" type="date" placeholder="请选择日期" clearable />
              </el-form-item>
              <el-form-item>
                <el-button type="primary" @click="onSubmit">查询</el-button>
                <el-button type="default" @click="onCancel">重置</el-button>
              </el-form-item>
            </el-form>
          </div>
        </template>
      </el-card>
  
      <el-card style="width: 100%" shadow="hover">
        <template #default>
          <div class="grid-default">
            <div class="default-file">
              <!-- 核心属性详解 -->
              <!-- accept          属性‌：用于指定可接受的文件类型，多个MIME类型用英文逗号分隔 2。例如accept="image/*,.pdf"表示接受所有图片和PDF文件。 -->
              <!-- ‌multiple        属性‌：设置后允许用户选择多个文件，此时value值为第一个文件的虚拟路径 2。 -->
              <!-- ‌required        属性‌：标记该文件字段为必填项，如果为空则表单无法提交 1 4。 -->
              <!-- ‌capture         属性‌：在移动设备上指定捕获媒体的方式，如capture="camera"直接调用摄像头 1。 -->
              <!-- 事件与方法 -->
              <!-- ‌change          事件‌：当用户选择文件后触发，可用于实时获取文件信息 1 7。 -->
              <!-- ‌files           属性‌：通过JavaScript的File API访问已选择的文件列表，返回FileList对象 1 7。 -->
              <!-- ‌value           属性‌：包含已选择文件的路径字符串，选择多个文件时表示第一个文件的路径 1 2。 -->
              <!-- 浏览器特定功能 -->
              <!-- ‌webkitdirectory 属性‌：在Chrome和Safari浏览器中支持选择整个目录而非单个文件 5。 -->
              <!-- 使用注意事项 -->
              <!-- 注意：value属性不能与input type="file"一起使用，文件值需要通过files属性获取 3。 -->
              <!-- 文件选择控件的外观受浏览器限制，但可以通过CSS进行一定程度的样式定制 2。 -->
              <input type="file" id="formFile" name="userFile" ref="singleFileRef" accept="image/*,.pdf" multiple="false" required capture="camera" class="file-input" @change="handleSingleFile">
              <el-tag type="danger" v-if="formFileName">文件名:{{ formFileName }},&nbsp;大小:{{ formFileSize }}kb,&nbsp;类型:{{ formFileType }}</el-tag>
            </div>
            <br />
            <div class="default-btns">
              <div class="mb-4">
                <el-button type="primary" icon="plus" @click="handleSave">新增</el-button>
                <el-divider direction="vertical" />
                <el-button type="success" icon="upload" @click="handleUpload">上传</el-button>
                <el-divider direction="vertical" />
                <el-button type="warning" icon="download" @click="handleDownload">下载</el-button>
                <el-divider direction="vertical" />
                <el-button type="danger" icon="delete">删除</el-button>
              </div>
              <div class="right">
                <div class="icons">
                  <el-icon @click="handleRefresh"><Refresh /></el-icon>
                </div>
                <div class="icons">
                  <el-icon @click="handleFullScreen"><FullScreen /></el-icon>
                </div>
                <div class="icons">
                  <el-icon @click="handleSetting"><Setting /></el-icon>
                </div>
              </div>
            </div>
            <br />
            <div class="default-grid">
              <el-table v-loading="loading" element-loading-text="加载中..." :data="tableData" border stripe height="60vh" style="width: 100%">
                <el-table-column header-align="center" align="center" type="selection" width="55" fixed />
                <el-table-column header-align="center" align="center" type="index" label="序号" width="55" fixed />
                <el-table-column header-align="center" align="center" prop="id" label="编码" width="180" show-overflow-tooltip />
                <el-table-column header-align="center" align="center" prop="name" label="姓名" width="120" show-overflow-tooltip />
                <el-table-column header-align="center" align="center" prop="age" label="年龄" width="120" show-overflow-tooltip />
                <el-table-column header-align="center" align="center" prop="gender" label="性别" width="120" show-overflow-tooltip />
                <el-table-column header-align="center" align="center" prop="department" label="部门" width="120" show-overflow-tooltip />
                <el-table-column header-align="center" align="center" prop="delivery" label="状态" width="120" show-overflow-tooltip>
                  <template #default="scope">
                    <el-tag v-if="scope.row.delivery" type="success">启用</el-tag>
                    <el-tag v-else type="danger">禁用</el-tag>
                  </template>
                </el-table-column>
                <el-table-column header-align="center" align="center" prop="address" label="地址" width="480" show-overflow-tooltip />
                <el-table-column header-align="center" align="center" prop="image" label="头像" width="220" show-overflow-tooltip>
                  <template #default="scope">
                    <el-image :src="scope.row.imageUrl" style="width: 40px; height: 40px" />
                  </template>
                </el-table-column>
                <el-table-column header-align="center" align="center" prop="creationDate" label="创建时间" width="280" show-overflow-tooltip />
                <el-table-column header-align="center" align="center" prop="updateDate" label="更新时间" width="280" show-overflow-tooltip />
                <el-table-column header-align="center" align="center" prop="operate" label="操作" min-width="120" fixed="right">
                  <template #default="scope">
                    <el-button link type="primary" size="small" @click="handleEdit(scope.row)">编辑</el-button>
                    <el-button link type="primary" size="small" @click="handleRemove(scope.row)">删除</el-button>
                  </template>
                </el-table-column>
              </el-table>
              <br />
              <div class="demo-pagination-block">
                <el-pagination
                  v-model:current-page="currentPage4"
                  v-model:page-size="pageSize4"
                  :page-sizes="[5, 10, 20, 50]"
                  :size="size4"
                  :disabled="disabled4"
                  :background="background4"
                  layout="total, sizes, prev, pager, next, jumper"
                  :total="total4"
                  @size-change="handleSizeChange4"
                  @current-change="handleCurrentChange4"
                />
              </div>
            </div>
          </div>
        </template>
      </el-card>
  
      <el-dialog v-model="dialogVisible" :title="dialogTitle" width="500" :before-close="handleClose">
        <template #default>
          <div class="dialog-default">
            <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="auto" style="max-width: 800px">
              <el-form-item prop="name" label="用户名字">
                <el-input v-model="ruleForm.name" placeholder="请输入" />
              </el-form-item>
              <el-form-item prop="age" label="用户年龄">
                <el-input-number v-model="ruleForm.age" :min="1" :max="100" />
              </el-form-item>
              <el-form-item prop="base64Data" label="用户头像">
                <el-upload
                  class="avatar-uploader"
                  action="#"
                  :auto-upload="false"
                  :on-change="handleFileChange"
                  :show-file-list="false"
                  :on-success="handleAvatarSuccess"
                  :before-upload="beforeAvatarUpload"
                >
                  <img v-if="ruleForm.base64Data" :src="ruleForm.base64Data" class="avatar" />
                  <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
                </el-upload>
              </el-form-item>
              <el-form-item prop="department" label="用户部门">
                <el-select v-model="ruleForm.department" placeholder="请选择">
                  <el-option label="客服部" value="客服部" />
                  <el-option label="销售部" value="销售部" />
                  <el-option label="研发部" value="研发部" />
                  <el-option label="财务部" value="财务部" />
                </el-select>
              </el-form-item>
              <el-form-item prop="gender" label="用户性别">
                <el-radio-group v-model="ruleForm.gender">
                  <el-radio value="男">男</el-radio>
                  <el-radio value="女">女</el-radio>
                </el-radio-group>
              </el-form-item>
              <el-form-item prop="creationDate" label="创建时间">
                <el-date-picker v-model="ruleForm.creationDate" type="date" placeholder="请选择" />
              </el-form-item>
              <el-form-item prop="updateDate" label="更新时间">
                <el-date-picker v-model="ruleForm.updateDate" type="date" placeholder="请选择" />
              </el-form-item>
              <el-form-item prop="type" label="旅游城市">
                <el-checkbox-group v-model="ruleForm.type">
                  <el-checkbox value="bj" name="type">北京市</el-checkbox>
                  <el-checkbox value="sh" name="type">上海市</el-checkbox>
                  <el-checkbox value="gz" name="type">广州市</el-checkbox>
                  <el-checkbox value="sz" name="type">深圳市</el-checkbox>
                </el-checkbox-group>
              </el-form-item>
              <el-form-item prop="delivery" label="状态">
                <el-switch v-model="ruleForm.delivery" @change="switchChange" />
              </el-form-item>
            </el-form>
          </div>
        </template>
        <template #footer>
          <div class="dialog-footer">
            <el-button type="primary" @click="handleConfirm(ruleFormRef)">确认</el-button>
            <el-button type="default" @click="handleCancel(ruleFormRef)">取消</el-button>
          </div>
        </template>
      </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, h } from "vue";
import type { FormInstance, FormRules, ComponentSize, UploadProps } from "element-plus";
import { ElMessage, ElMessageBox } from 'element-plus';
import { ElNotification } from 'element-plus';
import { pageProductApi, saveProductApi, editProductApi } from "@/api/product/index.ts";

const loading = ref(false)

const formInline = reactive({
  user: '',
  department: '',
  status: '',
  creationDate: '',
})
// 提交按钮
const onSubmit = () => {
  console.log('提交函数')
}
// 重置按钮
const onCancel = () => {
  console.log('重置按钮')
}

// ---------- ---------- ---------- 弹框相关内容 ---------- ---------- ---------- 

const dialogVisible = ref(false)
const dialogTitle = ref('')
const handleClose = (done: () => void) => {
  ElMessageBox.confirm('你真的要关闭这个窗口吗?')
    .then((res) => {
      console.log(res)
      done()
    })
    .catch((err) => {
      console.error(err)
    })
}
// 封装函数
const fileToBase64 = (file) => {
  return new Promise((resolve) => {
    const reader = new FileReader()
    reader.readAsDataURL(file)
    reader.onload = () => resolve(reader.result)
  })
}
// 图片转Base64位字符串
const handleFileChange = async (file) => {
  const previewUrl = URL.createObjectURL(file.raw)
  const base64 = await fileToBase64(file.raw)
  ruleForm.base64Data = base64
  console.log('转换成功函数:', ruleForm.base64Data)
}
// 上传成功
const handleAvatarSuccess: UploadProps['onSuccess'] = (response, uploadFile) => {
  ruleForm.imageUrl = URL.createObjectURL(uploadFile.raw!)
  console.log('上传成功函数:', ruleForm.imageUrl)
}
// 文件类型过滤+文件大小过滤
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
  if (rawFile.type !== 'image/jpeg') {
    ElMessage.error('头像图片必须是[JPG]格式')
    return false
  } else if (rawFile.size / 1024 / 1024 > 2) {
    ElMessage.error('头像图片大小不能超过[2MB]')
    return false
  }
  return true
}
// 状态切换
const switchChange = (val: boolean | string | number) => {
  console.log('switch change val:', val)
}

// ---------- ---------- ---------- 表单相关内容 ---------- ---------- ---------- 

interface RuleForm {
  name: string
  age: number
  imageUrl: string
  base64Data: string
  department: string
  gender: string
  delivery: boolean
  creationDate: string
  updateDate: string
  type: string[]
}
const ruleFormRef = ref<FormInstance>()
const ruleForm = reactive<RuleForm>({
  name: '',
  age: 0,
  imageUrl: '',
  base64Data: '',
  department: '',
  gender: '',
  delivery: false,
  creationDate: '',
  updateDate: '',
  type: [],
})
const rules = reactive<FormRules<RuleForm>>({
  name: [
    { required: true, message: 'Please input', trigger: 'blur' },
    { min: 3, max: 5, message: 'Length should be 3 to 5', trigger: 'blur' },
  ],
  age: [{ required: true, message: 'Please input', trigger: 'blur', }],
  base64Data: [{ required: true, message: 'Please select', trigger: 'change', }],
  department: [{ required: true, message: 'Please select', trigger: 'change', }],
  gender: [{ required: true, message: 'Please select', trigger: 'change', }],
  creationDate: [{ type: 'date', required: true, message: 'Please pick a date', trigger: 'change', }],
  updateDate: [{ type: 'date', required: true, message: 'Please pick a time', trigger: 'change', }],
  type: [{ type: 'array', required: true, message: 'Please select at least one activity type', trigger: 'change', }],
})
// 表单确认按钮
// ★★★★★ 表单校验：validate()     对整个表单的内容进行验证。接收一个回调函数，或返回：Promise 处理异步操作。 ★★★★★
const handleConfirm = async (formEl: FormInstance | undefined) => {
  console.log('200')
  if (!formEl) {
    return
  }
  console.log('201')
  // 方式一：异步操作Async+Await
  await formEl.validate((valid, fields) => {
    console.log('202')
    if (valid) {
      console.log('203')
      console.log('valid submit:', valid)
    } else {
      console.log('204')
      console.log('fields submit:', fields)
    }
    console.log('205')
  })
  // 方式二：异步操作Async+Await + 异常捕获Try...Catch...
  try {
    console.log('202')
    const flag = await ruleFormRef.value.validate()
    console.log('flag is:', flag)
    console.log('203')
  } catch (err) {
    console.log('204')
    console.error('error submit:', err)
  } finally {
    console.log('205')
  }
  // 方式三：异步操作Async+Await + 异常捕获.then()....catch()...
  await ruleFormRef.value.validate()
    .then((res) => {
      console.log('202')
      console.log('result submit:', res)
      console.log('203')
    })
    .catch((err) => {
      console.log('204')
      console.error('error submit:', err)
    })
    .finally(() => {
      console.log('205')
    })
  console.log('206')
  ElMessage({ message: 'This is a info message.', type: 'info' })
  ElMessage({ message: 'Congrats, this is a success message.', type: 'success' })
  ElMessage({ message: 'Warning, this is a warning message.', type: 'warning' })
  ElMessage({ message: 'Oops, this is a error message.', type: 'error' })
  ElMessage({ message: 'This is a primary message.', type: 'primary' })
  console.log('207')
  if (ruleForm.id) {
    let editData = {
      id: ruleForm.id,
      name: ruleForm.name,
      age: ruleForm.age,
      imageUrl: ruleForm.base64Data,
      department: ruleForm.department,
      gender: ruleForm.gender,
      creationDate: ruleForm.creationDate,
      updateDate: ruleForm.updateDate,
      address: ruleForm.address,
      delivery: ruleForm.delivery
    }
    console.log('208')
    await editProductApi(editData).then(res => {
      console.log('editProductApi res:', res.data)
    }).catch((err) => {
      console.error('editProductApi err:', err)
    }).finally(() => {
      console.log('editProductApi().finally(()=>{})')
    })
  } else {    
    let saveData = {
      id: "",
      name: ruleForm.name,
      age: ruleForm.age,
      imageUrl: ruleForm.base64Data,
      department: ruleForm.department,
      gender: ruleForm.gender,
      creationDate: ruleForm.creationDate,
      updateDate: ruleForm.updateDate,
      address: "广东省深圳市龙岗区坂田街道上雪村西三巷二号804室",
      delivery: ruleForm.delivery
    }
    console.log('208')
    await saveProductApi(saveData).then(res => {
      console.log('saveProductApi res:', res.data)
    }).catch((err) => {
      console.error('saveProductApi err:', err)
    }).finally(() => {
      console.log('saveProductApi().finally(()=>{})')
    })
  }
  console.log('209')
  formEl.resetFields()
  console.log('210')
  dialogVisible.value = false
}
// 表单取消按钮
// ★★★★★ 表单校验：resetFields()	重置该表单项，将其值重置为初始值，并移除校验结果。 ★★★★★
const handleCancel = (formEl: FormInstance | undefined) => {
  if (!formEl) {
    return
  } else {
    console.log('第一种表单校验格式a:', formEl)
    console.log('第一种表单校验格式b:', formEl.validate())
    console.log('第一种表单校验格式c:', formEl.resetFields())
    console.log('第二种表单校验格式x:', ruleFormRef.value)
    console.log('第二种表单校验格式y:', ruleFormRef.value.validate())
    console.log('第二种表单校验格式z:', ruleFormRef.value.resetFields())
    formEl.resetFields()
    ruleFormRef.value.resetFields()
    dialogVisible.value = false
  }
}

// 新增按钮
const handleSave = () => {
  dialogTitle.value = '新增用户信息'
  dialogVisible.value = true
}
// 编辑按钮
const handleEdit = (val) => {
  console.log('行数据:', val)
  Object.assign(ruleForm, val)
  console.log('表数据:', ruleForm)
  dialogTitle.value = '编辑用户信息'
  dialogVisible.value = true
}
// 删除按钮
const handleRemove = async (val) => {
  // 1.异步组件（ElMessageBox）方式一
  // try {    
  //   const res = await ElMessageBox.confirm(
  //     `您确定要删除编辑为【${val.id}】的这条数据吗？`,
  //     '警告',
  //     {
  //       confirmButtonText: '确定',
  //       cancelButtonText: '取消',
  //       type: 'warning',
  //     }
  //   );
  //   ElMessage({ type: 'success', message: '确定删除:' + res })
  //   ElNotification({ title: '通知组件', message: '确定删除:' + res, type: 'success' })
  // } catch (err) {
  //   ElMessage({ type: 'info', message: '取消删除:' + err })
  //   ElNotification({ title: '通知组件', message: '取消删除:' + err, type: 'info' })
  // }
  // 2.异步组件（ElMessageMax）方式二
  await ElMessageBox.confirm(
    `您确定要删除编辑为【${val.id}】的这条数据吗？`,
    '警告',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    }
  ).then((res) => {
    ElMessage({ type: 'success', message: '确定删除:' + res })
    ElNotification({ title: '通知组件', message: '确定删除:' + res, type: 'success' })
  }).catch((err) => {
    ElMessage({ type: 'info', message: '取消删除:' + err })
    ElNotification({ title: '通知组件', message: '取消删除:' + err, type: 'info' })
  });
}

// 附件按钮
const formFileName = ref("");
const formFileSize = ref("");
const formFileType = ref("");
const handleSingleFile = (event) => {
  const files = Array.from(event.target.files);
  files.forEach(async (element) => {
    console.log('上传奇文件:', element);    
    formFileName.value = element.name;
    formFileSize.value = element.size;
    formFileType.value = element.type;
    const formData = new FormData();
    formData.append("file", element);
    try {
      const response = await importFileApi(FormData, { headers: { "Content-Type": "multipart/form-data" }});
      console.log("文件导入成功:", response);
    } catch (error) {
      console.error("文件导入失败:", error);
    }
  });
}
// 上传按钮
const handleUpload = () => {

}
// 下载按钮
const handleDownload = () => {

}

// 刷新按钮
const handleRefresh = () => {
  try {    
    setTimeout(() => {
      initialDataFetch(currentPage4.value, pageSize4.value);
      ElMessage({ type: 'success', message: '刷新成功' });
      ElNotification({ title: '通知组件', message: '刷新成功', type: 'success' });
    }, 500);
  } catch (err) {
    ElMessage({ type: 'error', message: '刷新失败' + err });
    ElNotification({ title: '通知组件', message: '刷新失败' + err, type: 'error' });
  }
}
// 全屏按钮
const handleFullScreen = () => {
  console.log('全屏按钮');
}
// 设置按钮
const handleSetting = () => {
  console.log('设置按钮');
}

// 报错：Uncaught (in promise) TypeError: Assignment to constant variable. at initialDataFetch (index.vue?t=1756618286745:57:17)
// 解决：let 替换 const
let tableData = ref([])
let currentPage4 = ref(1)
let pageSize4 = ref(5)
let size4 = ref<ComponentSize>("default")
let disabled4 = ref(false)
let background4 = ref(true)
let total4 = ref(0)
let handleSizeChange4 = (val: number) => {
  console.log(`${val} items per page`)
  initialDataFetch(currentPage4.value, val)
}
let handleCurrentChange4 = (val: number) => {
  console.log(`current page: ${val}`)
  initialDataFetch(val, pageSize4.value)
}
let initialDataFetch = async (arg1, arg2) => {
  loading.value = true
  await pageProductApi({ currentPage: arg1, pageSize: arg2 })
    .then((res) => {
      if (res.data.records && Array.isArray(res.data.records)) {
        tableData.value = res.data.records
        total4.value = res.data.total
      }
    })
    .catch((err) => {
      console.error('apiProductBrandPage err:', err)
    })
    .finally(() => {
      setTimeout(() => {
        loading.value = false
      }, 500)
    })
}
onMounted(() => {
  initialDataFetch(currentPage4.value, pageSize4.value)
})
</script>

<style scoped lang="scss">
.bt822a {
  margin: 0;
  padding: 0;
  width: 100%;
  height: calc(100vh - 56px - 16px);
  background-color: #f8f8f8;
}
.grid-default {
  .default-btns {
    display: flex;
    justify-content: space-between;
    .right {
      display: flex;
      .icons {
        width: 32px;
        align-content: center;
        color: black;
        font-size: 20px;
      }
      .icons:hover {
        cursor: pointer;
        color: #1890ff;
        font-size: 22px;
      }
    }
  }
}

.demo-form-inline .el-input {
  --el-input-width: 220px;
}
.demo-form-inline .el-select {
  --el-select-width: 220px;
}

.demo-pagination-block + .demo-pagination-block {
  margin-top: 10px;
}
.demo-pagination-block .demonstration {
  margin-bottom: 16px;
}

.avatar-uploader .avatar {
  width: 178px;
  height: auto;
  display: block;
}
.avatar-uploader .el-upload {
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
}
.avatar-uploader .el-upload:hover {
  border-color: var(--el-color-primary);
}
.el-icon.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  text-align: center;
}
</style>
